﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;

/// <summary>
/// Summary description for Claim
/// </summary>
public class Claim
{
	public Claim()
	{
	}

    public int claimId { set; get; }
    public String claimantName { set; get; }
    public String claimantNric { set; get; }
    public DateTime claimantDob { set; get; }
    public String claimantRelationshipToPolicyOwner { set; get; }
    public string claimType { set; get; }
    public String claimDescription { set; get; }
    public decimal claimAmount { set; get; }
    public DateTime claimDate { set; get; }
    public String policyNo { set; get; }

    public void addNewClaim()
    {
        SqlConnection conn = DBManager.getSqlConnection();
        conn.Open();

        string sql = "INSERT R_CLAIM " +
                          " (policy_no, claimant_name, claimant_nric, claimant_dob, claimant_relationship, claim_type, claim_description, claim_amount, claim_date)" +
                    " VALUES(@policyNo, @claimantName, @claimantNric, @claimantDob, @claimantRelationship, @claimType, @claimDescription, @claimAmount, @claimDate)";

        var cmd = new SqlCommand(sql, conn);

        decimal zero = 0.0000m;
        cmd.Parameters.AddWithValue("@policyNo", policyNo);
        cmd.Parameters.AddWithValue("@claimantName", claimantName);
        cmd.Parameters.AddWithValue("@claimantNric", claimantNric);
        cmd.Parameters.AddWithValue("@claimantDob", claimantDob);
        cmd.Parameters.AddWithValue("@claimantRelationship", claimantRelationshipToPolicyOwner);
        cmd.Parameters.AddWithValue("@claimType", claimType);
        cmd.Parameters.AddWithValue("@claimDescription", claimDescription);
        cmd.Parameters.AddWithValue("@claimAmount", claimAmount);
        cmd.Parameters.AddWithValue("@claimDate", DateTime.Now);

        cmd.ExecuteNonQuery();


        conn.Close();


    }


    public static List<Claim> getPolicyClaims(string policyNo, String claimType)
    {
        var claims = new List<Claim>();
        SqlConnection conn = DBManager.getSqlConnection();
        conn.Open();

        string sql = "select claim_id,claimant_name,claimant_nric, claimant_dob, claimant_relationship,claim_type,claim_description,claim_amount,claim_date " +
                     " from R_CLAIM" +
                     " where policy_no ='" + policyNo + "'";

        if (!Util.IsBlank(claimType))
        {
            sql = sql + " and claim_type = '" + claimType + "'";
        }

        SqlCommand cmd = new SqlCommand(sql, conn);
        SqlDataReader dr = cmd.ExecuteReader();

        while (dr.Read())
        {
            Claim claim = new Claim();
            claim.policyNo = policyNo;
            claim.claimId = dr.GetInt32(0);
            claim.claimantName = dr.GetString(1);
            claim.claimantNric = dr.GetString(2);
            claim.claimantDob = dr.GetDateTime(3);
            claim.claimantRelationshipToPolicyOwner = dr.GetString(4);
            claim.claimType = dr.GetString(5);
            claim.claimDescription = dr.GetString(6);
            claim.claimAmount = dr.GetDecimal(7);
            claim.claimDate = dr.GetDateTime(8);
            claims.Add(claim);
        }

        dr.Close();

        cmd.ExecuteNonQuery();
        conn.Close();

        return claims;
    }

    public void claim(string policyNo, string claimType, decimal claimAmount)
    {
        this.claimType = claimType;
        this.policyNo = policyNo;
        Policy policy = Policy.getPolicy(policyNo);
        
        List<Claim> claimHistroy = Claim.getPolicyClaims(policyNo, claimType);
        
        //Check if this claimType was claimed before
        if (claimHistroy != null && claimHistroy.Count > 0) throw new RetirementException(RetirementException.NO_EXISTING_PLUS_RIDER, claimType + " was claimed before");

        //Claims for Angioplasty and other Critical Illnesses are only available for Critical Care Plus Rider
        if (("ANGIOPLASTY").Equals(claimType))
        {
            //Check if the policy consists of  Critical Care Plus Rider
            if (policy.plusRiderSumInsured < 0) throw new RetirementException(RetirementException.NO_EXISTING_PLUS_RIDER);

            //According to government rules, max claim amount for Angioplasty is $25000 or 10% of critical illness sum insured (whichever is lower)
            decimal max = 25000;

            if (policy.plusRiderSumInsured * (Decimal)0.1 < max)
            {
                max = policy.plusRiderSumInsured * (Decimal)0.1;
            }

            if (claimAmount > max)
            {
                throw new RetirementException(RetirementException.CLAIM_AMOUNT_OVER_MAX, "Maximum claim amount for Angioplasty is " + max);
            }

            this.claimAmount = claimAmount;

            policy.plusRiderSumInsured = policy.plusRiderSumInsured - claimAmount;
            policy.updatePolicy(policy.policyNo);

        }
        else if (("CRITICAL_ILLNESS").Equals(claimType))
        {
            //Check if the policy consists of  Critical Care Plus Rider
            if (policy.plusRiderSumInsured < 0) throw new RetirementException(RetirementException.NO_EXISTING_PLUS_RIDER);
            /*
            List<Claim> angioplastyClaimHistroy = Claim.getPolicyClaims(policyNo, "ANGIOPLASTY");
            decimal claimedAmount = 0;
            
            foreach (Claim claim in angioplastyClaimHistroy)
            {
                claimedAmount = claim.claimAmount + claimedAmount;
            }


            if (claimAmount > (policy.plusRiderSumInsured - claimedAmount) )
            {
                throw new RetirementException(RetirementException.CLAIM_AMOUNT_OVER_MAX, "Maximum claim amount for CRITICAL_ILLNESS is " + (policy.plusRiderSumInsured - claimedAmount));
            }
            */
            this.claimAmount = policy.plusRiderSumInsured;
            policy.plusRiderSumInsured = 0;
            policy.waiverRiderPremium = 0;
            policy.updatePolicy(policy.policyNo);
        }
            //For Disability, Terminal Illnesses and Death
        else
        {
            decimal accountValue = policy.checkAccountValue(DateTime.Now);
            decimal maxClaimAmount = policy.basicSumInsured > accountValue ? policy.basicSumInsured : accountValue;

            if (maxClaimAmount < claimAmount) 
            {
                throw new RetirementException(RetirementException.CLAIM_AMOUNT_OVER_MAX, "Maximum claim amount for " + claimType + " is " + policy.plusRiderSumInsured);
            }

            this.claimAmount = maxClaimAmount;

            policy.basicSumInsured = 0;
            policy.plusRiderSumInsured = 0;
            policy.waiverRiderPremium = 0;
            policy.status = "INACTIVE";
            policy.updatePolicy(policy.policyNo);
 
        }

        this.policyNo = policy.policyNo;
        this.addNewClaim();

        //Pay the basic sum insured or account value to client (whichever is higher)
        new Payment().payClaim(policy.accountId, policyNo, this.claimAmount);
        

    }


    public Decimal getMaxClaimAmount(string policyNo, string claimType)
    {
        decimal maxClaimAmount = 0;

        this.claimType = claimType;
        this.policyNo = policyNo;
        Policy policy = Policy.getPolicy(policyNo);

        List<Claim> claimHistroy = Claim.getPolicyClaims(policyNo, claimType);

        //Check if this claimType was claimed before
        if (claimHistroy != null && claimHistroy.Count > 0) throw new RetirementException(RetirementException.NO_EXISTING_PLUS_RIDER, "Claimed Before!");

        //Claims for Angioplasty and other Critical Illnesses are only available for Critical Care Plus Rider
        if (("ANGIOPLASTY").Equals(claimType))
        {
            //Check if the policy consists of  Critical Care Plus Rider
            if (policy.plusRiderSumInsured < 0) throw new RetirementException(RetirementException.NO_EXISTING_PLUS_RIDER);

            //According to government rules, max claim amount for Angioplasty is $25000 or 10% of crital illness sum insured (whichever is lower)
            decimal max = 25000;

            if (policy.plusRiderSumInsured * (Decimal)0.1 < max)
            {
                max = policy.plusRiderSumInsured * (Decimal)0.1;
            }

            maxClaimAmount = max;
        }
        else if (("CRITICAL_ILLNESS").Equals(claimType))
        {
            //Check if the policy consists of  Critical Care Plus Rider
            if (policy.plusRiderSumInsured < 0) throw new RetirementException(RetirementException.NO_EXISTING_PLUS_RIDER);

            /*
            List<Claim> angioplastyClaimHistroy = Claim.getPolicyClaims(policyNo, "ANGIOPLASTY");
            decimal claimedAmount = 0;

            foreach (Claim claim in angioplastyClaimHistroy)
            {
                claimedAmount = claim.claimAmount + claimedAmount;
            }
            

            if (claimAmount > (policy.plusRiderSumInsured - claimedAmount))
            {
                throw new RetirementException(RetirementException.CLAIM_AMOUNT_OVER_MAX, "Maximum claim amount for CRITICAL_ILLNESS is " + (policy.plusRiderSumInsured - claimedAmount));
            }
            */
            maxClaimAmount = policy.plusRiderSumInsured;        
        }
        //For Disability, Terminal Illnesses and Death
        else
        {
            decimal accountValue = policy.checkAccountValue(DateTime.Now);
            maxClaimAmount = policy.basicSumInsured > accountValue ? policy.basicSumInsured : accountValue;
        }


        return maxClaimAmount;
    }


}